package com.ruoyi.activiti.service;

import com.alibaba.fastjson.JSONArray;
import com.ruoyi.activiti.domain.BizTodoItem;
import com.ruoyi.activiti.domain.FormData;
import com.ruoyi.activiti.domain.FormDef;
import com.ruoyi.activiti.mapper.FormMapper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class FormService{
    @Autowired
    private FormMapper formMapper;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private IProcessService processService;

    @Autowired
    IBizTodoItemService bizTodoItemService;

    public void startProcessByForm(Integer formId, Integer fromDataId){
        //获取表单关联的流程key
        FormDef formDef = formMapper.selectFormDefById(formId);
        String processDef = formDef.getProcessDef();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDef).singleResult();
        String processKey = processDefinition.getKey();
        //获取业务数据
        FormData formData = formMapper.selectFormDataById(fromDataId);
        String jsonData = formData.getFormData();
        //业务数据转流程变量
        Map attr = getMapFromFormData(jsonData);
        //开启流程，更新业务数据建立双向关联
        ProcessInstance processInstance = processService.submitApply(ShiroUtils.getLoginName() , fromDataId.toString(), formData.getTitle() , processKey,attr);
        formData.setProcessIns(processInstance.getId());
        formMapper.updateFormData(formData);
    }

    public void complateByForm(String taskId,String formData,Integer formDataId){
        //更新业务数据
        FormData newFormData = formMapper.selectFormDataById(formDataId);
        newFormData.setFormData(formData);
        newFormData.setId(formDataId);
        formMapper.updateFormData(newFormData);
        //完成任务
        Map attr = getMapFromFormData(formData);
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        complete(task,newFormData.getTitle(), attr);
    }

    public FormData getFormDataFromTaskId(String taskId){
        //根据任务获取流程实例
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        String processInstanceId = task.getProcessInstanceId();
        //根据流程实例获取关联的业务数据
        String businessKeyByInstanceId = processService.findBusinessKeyByInstanceId(processInstanceId);
        Integer businessKey = Integer.valueOf(businessKeyByInstanceId);
        FormData formData = formMapper.selectFormDataById(businessKey);
        return formData;
    }

    public void saveFormDef(FormDef formDef) {
        formMapper.saveFormDef(formDef);
    }

    public void updateFormDef(FormDef formDef) {
        formMapper.updateFormDef(formDef);
    }

    public void linkProcess(String processDefinitionId, Integer formId){
        FormDef formDef = new FormDef();
        formDef.setId(formId);
        formDef.setProcessDef(processDefinitionId);
        formMapper.linkProcess(formDef);
    }

    public void saveFormData(FormData formData) {
        formMapper.saveFormData(formData);
    }

    public List<FormDef> listFormDef(FormDef formDef) {
        return formMapper.listFormDef(formDef);
    }

    public FormDef selectFormDefById(Integer id) {
        return formMapper.selectFormDefById(id);
    }

    public List<FormData> listFormData(FormData formData) {
        return formMapper.listFormData(formData);
    }

    public FormData selectFormDataById(Integer id) {
        return formMapper.selectFormDataById(id);
    }

    public void updateFormData(FormData formData) {
        formMapper.updateFormData(formData);
    }

    //将jqueryBuilder生成的json数据转为Activiti使用的变量
    public Map getMapFromFormData(String formData){
        List<Map> maps = JSONArray.parseArray(formData, Map.class);
        Map attr = new HashMap();
        for(Map map : maps){
            if(map.containsKey("userData")){
                JSONArray userData = (JSONArray) map.get("userData");
                userData.toJavaList(String.class);
                userData.forEach((item)->{
                    attr.put(map.get("label").toString(),item);
                });
            }
        }
        return attr;
    }

    //插入流转历史，完成任务，修改待办信息
    public void complete(Task task, String title, Map<String, Object> variables) {
        String taskId = task.getId();
        String instanceId = task.getProcessInstanceId();
        //流转历史
        String comment = variables.toString();// 批注
        taskService.addComment(taskId, instanceId, comment);
        //完成任务
        taskService.resolveTask(taskId, variables);
        if(task.getClaimTime() == null){
            taskService.claim(taskId,ShiroUtils.getLoginName());
        }
        taskService.complete(taskId, variables);
        //更新任务待办信息
        BizTodoItem query = new BizTodoItem();
        query.setTaskId(taskId);
        List<BizTodoItem> updateList = CollectionUtils.isEmpty(bizTodoItemService.selectBizTodoItemList(query)) ? null : bizTodoItemService.selectBizTodoItemList(query);
        for (BizTodoItem update : updateList) {
            //修改当前用户的待办信息
            if (update.getTodoUserId().equals(ShiroUtils.getLoginName())) {
                update.setIsView("1");
                update.setIsHandle("1");
                update.setHandleUserId(ShiroUtils.getLoginName());
                update.setHandleUserName(ShiroUtils.getSysUser().getUserName());
                update.setHandleTime(DateUtils.getNowDate());
                bizTodoItemService.updateBizTodoItem(update);
            } else {
                //删除候选用户的待办信息
                bizTodoItemService.deleteBizTodoItemById(update.getId());
            }
        }
        //插入下一节点待办事项
        bizTodoItemService.insertTodoItem(instanceId, title, "key???");
    }
}
